;
; MODULE:         sys_boot.s
; PROJECT:        BlueStream
; MAINTAINER:     Ivan Griffin
; CREATION DATE:  28 September 2000
; DESCRIPTION:    common ARM system boot-code
;
; SOURCE CONTROL: $Id: sys_boot.s,v 1.9 2008/11/08 07:30:06 tianwq Exp $
;
; REVISION HISTORY:
;    14.Sept.2000         IG      Based on sys_boot.s for AEB
;
; LICENSE:
;     This source code is copyright (c) 2000-2004 Ceva Inc.,
;     All rights reserved.
;

    PRESERVE8
    AREA SYS_Boot, CODE, READONLY

    EXPORT SYSboot_Startup
    EXPORT SYSboot_Warm_Startup

    IF :DEF: ADS_TOOLCHAIN_SUPPORTED
      IMPORT main, WEAK
    ELSE
      IMPORT SYS_Main, WEAK
    ENDIF

    IMPORT SYSpost_Test, WEAK
    IMPORT hc_warm_reset, WEAK

    IMPORT SYSbuild_Info_Dummy, WEAK
    IMPORT SYS_Vector_Init_Block, WEAK            ; dummy to prevent linker
                                                  ; stripping vector table
    IMPORT SYSirq_SVC_Stack_Setup
    IMPORT SYSirq_IRQ_Stack_Setup
    IMPORT SYSirq_FIQ_Stack_Setup
    IMPORT SYSirq_SYS_Stack_Setup

;
; common ARM Definitions
;

MODE_USR            EQU         0x10
MODE_FIQ            EQU         0x11
MODE_IRQ            EQU         0x12
MODE_SVC            EQU         0x13
MODE_ABORT          EQU         0x14
MODE_UNDEF          EQU         0x15
MODE_SYS            EQU         0x1F
                                
I_BIT               EQU         0x80
F_BIT               EQU         0x40

;
; common ARM code
;

;
; THIS IS THE ENTRY POINT FOR THE ROM BUILD!!!
; On power-up, the flash is located at 0x00000000
; Program Counter starts at 0x00000000, and we jump to 
; high flash at 0x04000000
;
    IF :DEF: BUILD_FOR_ROM
    ENTRY
;       INFO 0, "Building for ROM"
    ENDIF
    LDR PC, =SYSboot_Startup

;
; FUNCTION:     SYSboot_Startup
; DESCRIPTION:  Cold-Boot Startup routine
;
SYSboot_Startup
    BL      _SYSboot_ZI_Init
    BL      _SYSboot_Copy_RWDATA_To_SRAM
    BL      SYSirq_IRQ_Stack_Setup
    BL      SYSirq_FIQ_Stack_Setup

    IF :DEF: ADS_TOOLCHAIN_SUPPORTED
        B       main                              ; and go!
    ELSE
        LDR PC, =SYS_Main                         ; and go!
    ENDIF

;
; FUNCTION:     SYSboot_Warm_Startup
; DESCRIPTION:  Warm-Boot Startup routine (i.e. as the result of a
;               HCI_RESET -- need to send HCI_Command_Complete when
;               boot has finished)
;
SYSboot_Warm_Startup
    BL      _SYSboot_ZI_Init
    BL     _SYSboot_Copy_RWDATA_To_SRAM
    BL     SYSirq_SVC_Stack_Setup
    BL     SYSirq_IRQ_Stack_Setup

    IF :DEF: ADS_TOOLCHAIN_SUPPORTED
        B       main                              ; and go!
    ELSE
        LDR PC, =SYS_Main                         ; and go!
    ENDIF

_Dummy
    LDR PC, =SYS_Vector_Init_Block            ; dummy to prevent linker - not working for ADS linker
    LDR PC, =SYSbuild_Info_Dummy              ; dummy to prevent linker - not working for ADS linker
                                                  ; stripping vector table
_SYSboot_halt   B       _SYSboot_halt             ; should never reach here!!!

; **********************************************************************

;
; Need to include Target Specific ARM Code
;
    INCLUDE sys_boot_chimera.s                    

; **********************************************************************

;
; Generic ARM routines to setup the LSRAM and SRAM and jump into C code
;

;
; FUNCTION:     _SYSboot_Copy_RWDATA_To_SRAM
; DESCRIPTION:  copy RW data section to SRAM
;
_SYSboot_Copy_RWDATA_To_SRAM
    IMPORT |Load$$SRAM_RW$$Base|, WEAK        ; Load Addr of RAM (Local RW) 
    IMPORT |Image$$SRAM_RW$$Base|, WEAK       ; Exec Addr of RAM (Local RW)
    IMPORT |Image$$SRAM_RW$$Length|, WEAK     ; Length of RAM Exec (Local RW)
    
    LDR     R0, =|Load$$SRAM_RW$$Base|
    LDR     R1, =|Image$$SRAM_RW$$Base|
    MOV     R2, R1
    LDR     R4, =|Image$$SRAM_RW$$Length|
    ADD     R2, R2, R4
    B       _copy

;
; FUNCTION:     _SYSboot_Copy_CODE_To_LSRAM
; DESCRIPTION:  copy vectors to LSRAM
;
_SYSboot_Copy_CODE_To_LSRAM

    IMPORT |Load$$LSRAM$$Base|, WEAK        ; Load Addr of RAM (Local RW) 
    IMPORT |Image$$LSRAM$$Base|, WEAK       ; Exec Addr of RAM (Local RW)
    IMPORT |Image$$LSRAM$$Length|, WEAK     ; Length of RAM Exec (Local RW)
    
    LDR     R0, =|Load$$LSRAM$$Base|
    LDR     R1, =|Image$$LSRAM$$Base|
    MOV     R2, R1
    LDR     R4, =|Image$$LSRAM$$Length|
    ADD     R2, R2, R4
    B       _copy

;
; FUNCTION:     _SYSboot_Setup_Temp_POST_Stack
; DESCRIPTION:  setup a temporary stack in LSRAM for power-on self test
;
_SYSboot_Setup_Temp_POST_Stack
    MOV     R0, #MODE_SVC:OR:I_BIT:OR:F_BIT
    MSR     CPSR_c, R0
    
    LDR     R13, =|Image$$LSRAM$$Base|
    LDR     R4, =|Image$$LSRAM$$Length|
    ADD     R13, R13, R4
    
    MOV     PC, LR

;
; FUNCTION:     _SYSboot_Copy_CODE_To_SRAM
; DESCRIPTION:  copy main stack code from FLASH/ROM to SRAM
;
_SYSboot_Copy_CODE_To_SRAM

    IMPORT |Load$$SRAM$$Base|, WEAK         ; Load Addr of RAM (RW) 
    IMPORT |Image$$SRAM$$Base|, WEAK        ; Exec Addr of RAM (RW)
    IMPORT |Image$$SRAM$$Length|, WEAK      ; Length of RAM Exec (RW)
    
    LDR     R0, =|Load$$SRAM$$Base|
    LDR     R1, =|Image$$SRAM$$Base|
    MOV     R2, R1
    LDR     R4, =|Image$$SRAM$$Length|
    ADD     R2, R2, R4
_copy                                       ; block copy function
    CMP r1, r2
    LDRLO   R3, [r0], #4
    STRLO   R3, [r1], #4
    BLO     _copy
    MOV     PC, LR

;
; FUNCTION:     _SYSboot_ZI_Init
; DESCRIPTION:  Initialise Zero-Init Data Segment
;
TOP_MEM_ADDR   EQU TOP_OF_MEMORY-16

_SYSboot_ZI_Init

    IMPORT |Image$$SYS_CONFIG$$ZI$$Base|, WEAK      ; Exec Addr of SYS_CONFIG (ZI)
    
    LDR R1, =TOP_MEM_ADDR
    LDR R0, =|Image$$SYS_CONFIG$$ZI$$Base|
    MOV R2, #0
_ZI_Loop
    CMP R0, R1
    STRLO R2, [R0], #4
    BLO _ZI_Loop
    MOV PC, LR

    IMPORT |Image$$LSRAM$$ZI$$Limit|, WEAK
    EXPORT __user_initial_stackheap

__user_initial_stackheap
    LDR R0, =|Image$$LSRAM$$ZI$$Limit|
    MOV PC, LR
 

    END
